package com.tengfei.api.user;

import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import com.tengfei.common.annotation.Anonymous;
import com.tengfei.common.constant.Constants;
import com.tengfei.common.core.domain.R;
import com.tengfei.common.core.domain.model.LoginBody;
import com.tengfei.common.enums.CaptchaType;
import com.tengfei.common.utils.StringUtils;
import com.tengfei.common.utils.redis.RedisUtils;
import com.tengfei.common.utils.reflect.ReflectUtils;
import com.tengfei.common.utils.spring.SpringUtils;
import com.tengfei.framework.config.properties.CaptchaProperties;
import com.tengfei.main.system.service.SysLoginService;
import com.tengfei.main.user.domain.bo.login.UserRegisterBo;
import com.tengfei.main.user.service.IUserLoginService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author feige
 * @version v1.0
 * @date 2022-08-14-14:39
 * @description 普通用户登录注册模块
 */

@RestController
@RequestMapping("/user/login")
@Validated
@Api(value = "用户登录注册控制器", tags = {"用户登录注册模块"})
public class UserLoginController {

    @Resource
    private IUserLoginService userLoginService;
    @Resource
    private CaptchaProperties captchaProperties;
    @Resource
    private SysLoginService loginService;

    @Anonymous
    @ApiOperation("用户登录")
    @PostMapping("/login")
    public R<Map<String, String>> login(@Validated @RequestBody LoginBody loginBody) {
        Map<String, String> ajax = new HashMap<>();
        // 生成令牌
        String token = loginService.login(loginBody, true);
        ajax.put(Constants.TOKEN, token);
        return R.ok(ajax);
    }

    /***
     * 用户注册
     */
    @Anonymous
    @ApiOperation("用户注册")
    @PostMapping("/register")
    public R<Void> register(@Validated @RequestBody UserRegisterBo user) {
        userLoginService.register(user);
        return R.ok();
    }

    /**
     * 查询部门简要信息
     */
    @Anonymous
    @ApiOperation("查询部门简要信息")
    @GetMapping("/deptList")
    public R<List<Map<String, Object>>> getDeptList() {
        List<Map<String, Object>> deptList = userLoginService.getDeptList();
        return R.ok(deptList);
    }


    /**
     * 生成验证码
     */
    @Anonymous
    @ApiOperation("生成验证码")
    @GetMapping("/captcha")
    public R<Map<String, Object>> getCode() {
        Map<String, Object> ajax = new HashMap<>();
        // 保存验证码信息
        String uuid = IdUtil.simpleUUID();
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
        // 生成验证码
        CaptchaType captchaType = captchaProperties.getType();
        boolean isMath = CaptchaType.MATH == captchaType;
        Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
        CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
        AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
        captcha.setGenerator(codeGenerator);
        captcha.createCode();
        String code = isMath ? getCodeResult(captcha.getCode()) : captcha.getCode();
        RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
        ajax.put("uuid", uuid);
        ajax.put("img", captcha.getImageBase64());
        return R.ok(ajax);
    }

    private String getCodeResult(String capStr) {
        int numberLength = captchaProperties.getNumberLength();
        int a = Convert.toInt(StringUtils.substring(capStr, 0, numberLength).trim());
        char operator = capStr.charAt(numberLength);
        int b = Convert.toInt(StringUtils.substring(capStr, numberLength + 1, numberLength + 1 + numberLength).trim());
        switch (operator) {
            case '*':
                return Convert.toStr(a * b);
            case '+':
                return Convert.toStr(a + b);
            case '-':
                return Convert.toStr(a - b);
            default:
                return StringUtils.EMPTY;
        }
    }

}
